#include <HeartMonitor.h>

//  VARIABLES
const int pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0 (Teensy 2.0 or teensy++2.0)
//const int tonePin = 10; // Speaker wire connected to pin 10 (Teensy 2.0) or pin 14 (teensy++2.0)
const int tonePin = 4; // Speaker wire connected to pin 10 (Teensy 2.0) or pin 14 (teensy++2.0)
const int blinkPin = 11; // on board LED connected to pin 11 (Teensy 2.0) or pin 6 (teensy++2.0)
int logCycle = 0;
int displayCycle = 0;
long bootTime;

#define SD_CS 0

//#define OLED_DC 8
//#define OLED_CS 23
//#define OLED_CLK 9
//#define OLED_MOSI 7 //Data
//#define OLED_RESET 4

#define OLED_DC 9
#define OLED_CS 23
#define OLED_CLK 8
#define OLED_MOSI 7 //Data
#define OLED_RESET 10

// Support classes
SDManager sdmanager = SDManager(); // create an instance for the user
InterruptHandler interruptHandler = InterruptHandler();
SSD1306ASCII oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void checkPulse() { // triggered when Timer fires
	cli();
	// disable interrupts while we do this
	interruptHandler.checkPulse();
	sei();

} // end isr

void setup() {
	delay(3000);
	pinMode(SD_CS, OUTPUT);
	pinMode(OLED_CS, OUTPUT);
	pinMode(blinkPin, OUTPUT); // pin that will blink to your heart beat!
	//this breaks teensy++2.0
	//pinMode(pulsePin, INPUT);
	Serial.begin(9600);
	setSyncProvider(RTC.get); // the function to get the time from the RTC
	Serial.println("Heart Monitor Initialising");
  if(timeStatus()!= timeSet)
	 Serial.println("Unable to sync with the RTC");
  else
	 Serial.println("RTC has set the system time");

	initialLCDDisplay();

	sdmanager.setup(SD_CS);
	sdmanager.init();
	sdmanager.loadConfiguration();

	interruptHandler.setup(blinkPin, pulsePin);
	FlexiTimer2::set(2, 1.0 / 1000, checkPulse); // call every 2ms "ticks"
	FlexiTimer2::start();
	bootTime = now();
}

void initialLCDDisplay() {
	oled.ssd1306_init(SSD1306_SWITCHCAPVCC);
	oled.clear();
	oled.setCursor(0,0);
	oled.println("starting");
	oled.setCursor(0,1);
	oled.println(sdmanager.dateString());

	Serial.println("updated display");
}

void loopLCDDisplay(const int displayBPM) {
	oled.clear();
	oled.setCursor(0,0);
	oled.print("pulse: ");
	oled.setCursor(11,0);
	oled.print(displayBPM, 10);
	oled.setCursor(0,1);
	oled.print("elapsed: ");
	oled.setCursor(11,1);
	oled.print(sdmanager.timeString(now() - bootTime));
	oled.setCursor(0,2);
	oled.println(sdmanager.dateString());
	Serial.print("pulse: ");
	Serial.println(displayBPM, 10);
}

void loop() {
	int BPM = interruptHandler.getCurrentBPM();
	if (BPM > -1) { // true when we find a heartbeat
		if (BPM < sdmanager.getLow()) {
			tone(tonePin, 100, 100);
		} else if (BPM > sdmanager.getHigh()) {
			tone(tonePin, 400, 100);
		} else {
			noTone(tonePin);
		}
	}
	if (displayCycle++ > 500) { // 500 happens about every 10 seconds
		int displayBPM = interruptHandler.getAverageBPM();
		displayCycle = 0;
		loopLCDDisplay(displayBPM);
	}
	if (logCycle++ > 3000) { // 3000 happens about once a minute
		sdmanager.logEntry(interruptHandler.getAverageBPM());
		logCycle = 0;
	}
	delay(20); //  take a break

}
#ifdef __cplusplus
int main(void) {
	_init_Teensyduino_internal_();

	setup();

	while (1) {
		loop();
	}
}
#endif
